# -*- python -*-
# ex: set syntax=python:
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# READ THIS:
# See http://dev.chromium.org/developers/testing/chromium-build-infrastructure

import socket

# These modules come from scripts, which must be in the PYTHONPATH.
from master import master_config
from master import master_utils
from master import slaves_list
from master.builders_pools import BuildersPools
from master.factory import annotator_factory
from master.factory import remote_run_factory
from master.try_job_http import TryJobHTTP

import config
import master_site_config

ActiveMaster = master_site_config.ChromiumPerfTryServer

def m_remote_run(recipe, factory_properties=None, **kwargs):
  if not factory_properties:
    factory_properties = {}
  if not factory_properties.get('path_config'):
    factory_properties['path_config'] = 'kitchen'
  return remote_run_factory.RemoteRunFactory(
      active_master=ActiveMaster,
      repository='https://chromium.googlesource.com/chromium/tools/build.git',
      recipe=recipe,
      factory_properties=factory_properties,
      **kwargs)


MAIL_NOTIFIER = ActiveMaster.is_production_host

# This is the dictionary that the buildmaster pays attention to. We also use
# a shorter alias to save typing.
c = BuildmasterConfig = {}

config.DatabaseSetup(c)

c['change_source'] = []

# Avoid merging requests.
c['mergeRequests'] = False

c['builders'] = []

_category_index = enumerate(
    ('builders', 'android', 'webview', 'windows', 'mac', 'linux', 'cq', 'fyi'))

_category_index = {category: index + 1 for index, category in _category_index}
def _CategoryIndex(category):
  return _category_index[category]

def _AddPinpointBuilder(name, platform, timeout=2400):
  factory_properties = {
      'append_deps_patch_sha': True,
      'build_url': master_config.GetGSUtilUrl('chrome-perf', name),
  }
  c['builders'].append({
      'name': name,
      'factory': m_remote_run(factory_properties=factory_properties,
                              recipe='chromium', timeout=timeout),
      'category': '%d%s|%s' % (_CategoryIndex('builders'), 'builders', platform)
  })

def _AddBisectBuilder(name, platform, upload_dir, timeout=2400):
  if platform == 'android':
    recipe = 'android/builder'
    factory = annotator_factory.AnnotatorFactory(ActiveMaster).BaseFactory
  else:
    recipe = 'chromium'
    factory = m_remote_run
  properties = {
      'append_deps_patch_sha': True,
      'build_url': master_config.GetGSUtilUrl('chrome-perf', upload_dir)}
  c['builders'].append({
      'name': '%s_bisect_builder' % name,
      'factory': factory(
          factory_properties=properties,
          recipe=recipe,
          timeout=timeout),
      'category': '%d%s|%s' % (_CategoryIndex('builders'), 'builders', platform)
  })

def _AddBisectBot(name, platform, category, timeout=3600, staging=False):
  if platform == 'android':
    recipe = 'bisection/android_bisect'
  else:
    recipe = 'bisection/desktop_bisect'

  name = '%s_perf_bisect' % name

  if staging:
    recipe += '_staging'
    name = 'staging_' + name


  c['builders'].append({
      'name': name,
      'factory': m_remote_run(
          recipe=recipe,
          timeout=timeout,
          max_time=24 * 60 * 60),
      'category': '%d%s|testers' % (_CategoryIndex(category), category)
  })

_AddPinpointBuilder('Mac Builder', 'mac')

# All builder bot names here are suffixed with '_bisect_builder'
_AddBisectBuilder('android_arm64_perf', 'android', 'android_perf_rel_arm64')
_AddBisectBuilder('android_perf', 'android', 'android_perf_rel')
_AddBisectBuilder('linux_perf', 'linux', 'Linux Builder')
_AddBisectBuilder('mac_perf', 'mac', 'Mac Builder')
_AddBisectBuilder('win_perf', 'win', 'Win Builder', timeout=4800)
_AddBisectBuilder('winx64', 'win', 'Win x64 Builder', timeout=4800)

# All bot names here are suffixed with '_perf_bisect'
_AddBisectBot('android_one', 'android', 'android')
_AddBisectBot('android_nexus5', 'android', 'android')
_AddBisectBot('android_nexus5X', 'android', 'android')
_AddBisectBot('android_nexus6', 'android', 'android')
_AddBisectBot('android_nexus7', 'android', 'android')

_AddBisectBot('win', 'win', 'windows')
_AddBisectBot('win_8', 'win', 'windows')
_AddBisectBot('win_x64', 'win', 'windows')
_AddBisectBot('winx64_10', 'win', 'windows')
_AddBisectBot('winx64ati', 'win', 'windows')
_AddBisectBot('winx64intel', 'win', 'windows')
_AddBisectBot('winx64nvidia', 'win', 'windows')
_AddBisectBot('winx64_zen', 'win', 'windows')
_AddBisectBot('winx64_high_dpi', 'win', 'windows')

_AddBisectBot('mac_10_11', 'mac', 'mac')
_AddBisectBot('mac_10_12', 'mac', 'mac')
_AddBisectBot('mac_retina', 'mac', 'mac')
_AddBisectBot('mac_pro', 'mac', 'mac')
_AddBisectBot('mac_air', 'mac', 'mac')
_AddBisectBot('mac_10_12_mini_8gb', 'mac', 'mac')

_AddBisectBot('linux', 'linux', 'linux')

_AddBisectBot('android_fyi', 'android', 'fyi')
_AddBisectBot('win_fyi', 'win', 'fyi')
_AddBisectBot('mac_fyi', 'mac', 'fyi')
_AddBisectBot('linux_fyi', 'linux', 'fyi')

_AddBisectBot('android_webview_arm64_aosp', 'android', 'webview')
_AddBisectBot('android_webview_nexus6_aosp', 'android', 'webview')

# Staging
_AddBisectBot('android_nexus5X', 'android', 'android', staging=True)
_AddBisectBot('linux', 'linux', 'linux', staging=True)
_AddBisectBot('mac_10_12', 'mac', 'mac', staging=True)
_AddBisectBot('win', 'win', 'windows', staging=True)

slaves = slaves_list.SlavesList('slaves.cfg', 'ChromiumPerfTryServer')

for builder in c['builders']:
  builder['slavenames'] = slaves.GetSlavesName(builder=builder['name'])
  builder.setdefault('auto_reboot', ActiveMaster.is_production_host)

c['slaves'] = master_utils.AutoSetupSlaves(c['builders'],
                                           config.Master.GetBotPassword())

master_utils.VerifySetup(c, slaves)

c['schedulers'] = []

pools = BuildersPools('chrome')
pools['chrome'].extend([builder['name'] for builder in c['builders']])

code_review_sites = {'chrome': ActiveMaster.code_review_site}

c['schedulers'].append(TryJobHTTP(
      name='try_job_http',
      port=ActiveMaster.try_job_port,
      code_review_sites=code_review_sites,
      pools=pools))

# Buildbot master url:
# Must come before AutoSetupMaster().
if ActiveMaster.is_production_host:
  c['buildbotURL'] = ActiveMaster.buildbot_url
else:
  c['buildbotURL'] = 'http://%s:%d/' % (
      socket.getfqdn(), ActiveMaster.master_port)

# Adds common status and tools to this master.
# Use our own mail notifier.
master_utils.AutoSetupMaster(c, ActiveMaster,
    mail_notifier=False,
    public_html='../master.chromium/public_html',
    templates=['../master.chromium/templates'])

if MAIL_NOTIFIER:
  # Add a dumb MailNotifier first so it will be used for BuildSlave with
  # notify_on_missing set when they go missing.
  from buildbot.status import mail
  c['status'].append(mail.MailNotifier(
      fromaddr=ActiveMaster.from_address,
      builders=[],
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))

  # Try job result emails.
  from master.try_mail_notifier import TryMailNotifier
  c['status'].append(TryMailNotifier(
      fromaddr=ActiveMaster.from_address,
      reply_to=ActiveMaster.reply_to,
      subject="try %(result)s for %(reason)s @ r%(revision)s",
      mode='all',
      relayhost=config.Master.smtp,
      lookup=master_utils.UsersAreEmails()))
else:
  from buildbot.status import mail
  c['status'].append(mail.MailNotifier(
      fromaddr=ActiveMaster.from_address,
      builders=[],
      relayhost=config.Master.smtp,
      extraRecipients=['robertocn@chromium.org']))


# The followings are what is kept on disk.
# Keep last try jobs, the default is too low. Must keep at least a few days
# worth of try jobs. 3000 is not even a full day but the server is full. Keep
# more build objects than log since they are much smaller.
c['buildHorizon'] = 6000
c['logHorizon'] = 3000
# Must be at least 2x the number of slaves.
c['eventHorizon'] = 200
c['logCompressionLimit'] = False

# Adjust the buildCaches to be 3x the number of slaves per builder.
c['autoBuildCacheRatio'] = 3

c['projectURL'] = 'http://dev.chromium.org/developers/testing/try-server-usage'

# vi: set ts=4 sts=2 sw=2 et:
